/**
 *
 * Copyright by Samuel Castro, 2011
 * All Rights Reserved
 *
 * NOTES:
 * Please do not redistribute this plugin without my permission
 */
package com.SySammy.Syraffle.Cmds;

import com.SySammy.Syraffle.Raffle;
import com.SySammy.Syraffle.RaffleConfig;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

public class RaffleHandler {

    private Raffle plugin;
    public static ArrayList<String> Tickets = new ArrayList<String>();
    public static HashMap<String, ArrayList<String>> Buyers = new HashMap<String, ArrayList<String>>();
    private static String PlayerName;

    public RaffleHandler(Raffle aThis) {
        this.plugin = aThis;
    }

    private RaffleConfig OpenDataBase(String ply) {
        String p = ply;
        RaffleConfig persistenceClass = plugin.getDatabase().find(RaffleConfig.class).where().ieq("PlayerName", p).findUnique();
        if (persistenceClass == null) {
            persistenceClass = new RaffleConfig();
        }
        return persistenceClass;
    }

    public void RaffleInfo(Player p) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        p.sendMessage(ChatColor.GREEN + "Raffle information:");
        p.sendMessage(ChatColor.GOLD + "Prize: " + ChatColor.GREEN + Rcfg.getPrizeQnt() + "x of " + Rcfg.getPrizeMaterial());
        p.sendMessage(ChatColor.GOLD + "Cost: " + ChatColor.GREEN + Rcfg.getCostQnt() + "x of " + Rcfg.getCostMaterial() + " per Ticket");
    }

    private boolean HasItemStack(Player p, ItemStack prize, String mat, int qnt) {
        HashMap<Integer, ItemStack> removeItem = p.getInventory().removeItem(prize);
        if (removeItem.size() <= 0) {
            return true;
        } else {
            for (int x = 1; x < removeItem.size(); x++) {
                p.getInventory().addItem(new ItemStack(Material.getMaterial(mat), qnt - removeItem.get(x).getAmount()));
            }
            return false;
        }
    }

    public boolean SetRafflePrize(Player p, String mat, int qnt) {
        PlayerName = p.getName();
        if (!HasItemStack(p, new ItemStack(Material.getMaterial(mat), qnt), mat, qnt)) {
            p.sendMessage(ChatColor.RED + "You don't have the required ItemStack.");
            return false;
        }
        p.sendMessage(ChatColor.GREEN + "Prize added, use '-c' to specify ticket cost.");
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        Rcfg.setPlayerName(p.getName());
        Rcfg.setPrizeMaterial(mat);
        Rcfg.setPrizeQnt(qnt);
        plugin.getDatabase().save(Rcfg);
        return true;
    }

    public boolean SetRaffleCost(Player p, String mat, int price) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        Rcfg.setCostMaterial(mat);
        Rcfg.setCostQnt(price);
        plugin.getDatabase().save(Rcfg);
        p.sendMessage(ChatColor.GREEN + "Price added, use '-t' to specify quantiy and time.");
        return true;
    }

    public boolean SetRaffleTimeQnt(Player p, int qnt, int time) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        Rcfg.setRaffleTime(time);
        Rcfg.setTicketQnt(qnt);
        plugin.getDatabase().save(Rcfg);
        p.sendMessage(ChatColor.GREEN + "Time and qnt added, use '-s' to start the raffle.");
        return true;
    }

    public ArrayList<String> MakeTickets(Player p) {
        ArrayList<String> Tset = new ArrayList<String>();
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        for (int x = 0; x < Rcfg.getTicketQnt(); x++) {
            Tset.add(p.getName().toUpperCase().subSequence(0, 3).toString() + "-" + String.valueOf(x + 1));
        }
        return Tset;
    }

    public void StartRaffle(Player p) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        Tickets.addAll(MakeTickets(p));
        plugin.getServer().broadcastMessage(ChatColor.GOLD + "[Info]: " + ChatColor.GREEN + "A raffle just started, information");
        plugin.getServer().broadcastMessage(ChatColor.GOLD + "Prize: " + ChatColor.GREEN + Rcfg.getPrizeQnt() + "x of " + Rcfg.getPrizeMaterial());
        plugin.getServer().broadcastMessage(ChatColor.GOLD + "Cost: " + ChatColor.GREEN + Rcfg.getCostQnt() + "x of " + Rcfg.getCostMaterial() + " per Ticket");
        plugin.Scheduler().scheduleSyncDelayedTask(plugin, new Tombola(), 20L * 60 * Rcfg.getRaffleTime());
        plugin.Scheduler().scheduleSyncRepeatingTask(plugin, new Announcer(), 21L * 60, 20L * 60);
    }

    public void BuyRaffle(Player p, int qnt) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        if (!HasItemStack(p, new ItemStack(Material.getMaterial(Rcfg.getCostMaterial()), Rcfg.getCostQnt() * qnt), Rcfg.getCostMaterial(), Rcfg.getCostQnt() * qnt)) {
            return;
        }

        ArrayList<String> BoughtTickets;
        if (Buyers.get(p.getName()) == null) {
            BoughtTickets = new ArrayList<String>();
        } else {
            BoughtTickets = Buyers.get(p.getName());
        }

        for (int x = 0; x < qnt; x++) {
            String ticket = Tickets.get(x);
            BoughtTickets.add(ticket);
        }

        Tickets.removeAll(BoughtTickets);
        Buyers.put(p.getName(), BoughtTickets);
    }

    private String FindWinner(String p) {
        RaffleConfig Rcfg = OpenDataBase(PlayerName);
        int ticketQnt = Rcfg.getTicketQnt();
        Random rand = new Random();
        int RandTicket = rand.nextInt(ticketQnt) + 1;
        String WinnerTicket = (String) PlayerName.toUpperCase().subSequence(0, 3) + "-" + String.valueOf(RandTicket);

        String Winner = null;
        if (Buyers == null) {
            plugin.getServer().broadcastMessage(ChatColor.GREEN + "[Info]: No one bought the winning raffle ticket.");
            plugin.getServer().broadcastMessage(ChatColor.GREEN + "Prize donated to the save a creeper foundation");
            return null;
        }

        Object[] KeyArray = Buyers.keySet().toArray();
        for (int y = 0; y < KeyArray.length; y++) {
            boolean contains = Buyers.get((String) KeyArray[y]).contains(WinnerTicket);
            if (contains == true) {
                Winner = (String) Buyers.keySet().toArray()[y];
                plugin.getServer().broadcastMessage(ChatColor.GREEN + "[Info]: Raffle results are in, the winner is: " + ChatColor.GOLD + Winner);
                return Winner;
            }
        }
        plugin.getServer().broadcastMessage(ChatColor.GREEN + "[Info]: No one bought the winning raffle ticket.");
        plugin.getServer().broadcastMessage(ChatColor.GREEN + "Prize donated to the save a creeper foundation");
        return null;
    }

    private void GivePrize(String p) {
        try {
            RaffleConfig Rcfg = OpenDataBase(PlayerName);
            Player player = plugin.getServer().getPlayer(p);
            player.getInventory().addItem(new ItemStack(Material.getMaterial(Rcfg.getPrizeMaterial()), Rcfg.getPrizeQnt()));
        } catch (NullPointerException e) {
        }
    }

    private class Tombola implements Runnable {

        public void run() {
            String FindWinner = FindWinner(PlayerName);
            GivePrize(FindWinner);
            plugin.Scheduler().cancelAllTasks();
            Tickets.clear();
            Buyers.clear();
            RaffleConfig Rcfg = OpenDataBase(PlayerName);
            plugin.getDatabase().delete(RaffleConfig.class, "PlayerId");
            plugin.getDatabase().save(Rcfg);
            PlayerName = null;
            RaffleCmds RC = new RaffleCmds(plugin);
            RaffleCmds.RaffleStarted = false;
            RC.Cfg.clear();
        }
    }

    private class Announcer implements Runnable {

        public void run() {
            plugin.getServer().broadcastMessage(ChatColor.GOLD + "[Info]: " + ChatColor.GREEN + "Don't forget to buy a raffle ticket!");
        }
    }
}
